package com.gitee.cnlongdb.basic.entity.query;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;

import com.gitee.cnlongdb.basic.enums.sort.LongDbSortMode;
import com.gitee.cnlongdb.basic.enums.sort.LongDbSortTypes;

/**
 * 系统名称：LongDbQuery.java
 * 模块名称：
 * 模块描述：longdb - 查询对象
 * 功能列表：
 * 模块作者：ZOUYONG
 * 开发时间：2018年12月5日 下午9:56:03
 * 模块路径：com.gitee.cnlongdb.basic.entity.query.LongDbQuery
 * 更新记录：
 */
public class LongDbQuery {
	
	// 需要查询的数据集合
	public final Map<String, LongDbWhere> longWhereMap = new LinkedHashMap<String, LongDbWhere>();
	
	// 需要排序的数据集合
	private final List<LongDbSort> sortList = new ArrayList<LongDbSort>();
	
	// 需要关联查询的表
	private final List<LongDbJoinWhere> joinWhereList = new ArrayList<LongDbJoinWhere>();
	
	// 查询后要转换的实体类
	private Class<?> classz;
	
	// 查询的表名称（为空时取classz的类名）
	private String tableName;
	
	/**
	 * 年月日区间查询
	 * 1、查询两个时间段，格式: 2018-01-01;2018-01-10 (用[;]分号隔开，查询1号到10号的数据)
	 * 2、查询多个时间段，格式：2018-01-01;2018-01-10&2018-02-01;2018-02-10(用[&]分号隔开，查询1月和2月的1号到10号的数据)
	 */
	private String yearMothDayArys;
	
	// 分页页码
	private Integer pageNo;
	// 分页每页显示数量
	private Integer pageSize;
	// 起止数据量
	private Integer start;
	// 结束数据量
	private Integer total;
	// 当前查询的总数量
	private Long queryTotalCount;
	// 查询符合条件的数据(默认不是查询数量)
	private boolean isQueryCount = false;
	// 是否需要分页(默认需要分页)
	private boolean isNeedPage = true;
	// 是否需要转化成对象
	private boolean transObject = true;
	
	/**
	 * 功能描述：添加要查询的数据
	 * 模块作者：ZOUYONG
	 * 开发时间：2018年11月11日 下午4:03:29
	 * 更新记录：
	 * 返回数据：LongDbQuery
	 */
	public LongDbQuery addLongDbWhere(LongDbWhere longWhere) {
		validLongWhere(longWhere);
		LongDbWhere existing = this.longWhereMap.get(longWhere.getWhereKey());
		String key = longWhere.getWhereKey();
		if (existing == null) {
			this.longWhereMap.put(key, longWhere);
		} else {
			throw new RuntimeException("该查询条件已存在！");
		}
		return this;
	}

	/**
	 * 功能描述：添加需要排序的数据
	 * 模块作者：ZOUYONG
	 * 开发时间：2018年11月11日 下午4:05:29
	 * 更新记录：
	 * 返回数据：LongDbQuery
	 */
	public LongDbQuery addSort(String field, LongDbSortMode asc, LongDbSortTypes type) {
		if(StringUtils.isBlank(field) || null == asc || null == type) {
			return this;
		}
		LongDbSort sort = new LongDbSort(field, asc.name(), type.name());
		this.sortList.add(sort);
		return this;
	}

	/**
	 * 功能描述：连接查询
	 * 模块作者：ZOUYONG
	 * 开发时间：2018年11月30日 下午11:59:37
	 * 更新记录：
	 * 返回数据：LongDbWhere
	 */
	public LongDbQuery joinWhere(LongDbJoinWhere joinWhere) {
		validJoinWhere(joinWhere);
		this.joinWhereList.add(joinWhere);
		return this;
	}
	
	/**
	 * 功能描述：对象查询条件进行校验
	 * 模块作者：ZOUYONG
	 * 开发时间：2018年12月1日 上午11:05:26
	 * 更新记录：
	 * 返回数据：void
	 */
	private void validLongWhere(LongDbWhere longWhere) {
		if(null == longWhere) {
			throw new RuntimeException("要查询的对象不能为空！");
		}
		if(StringUtils.isBlank(longWhere.getWhereKey())) {
			throw new RuntimeException("要查询的字段不能为空！");
		}
	}
	
	/**
	 * 功能描述：对关联查询的对象进行校验
	 * 模块作者：ZOUYONG
	 * 开发时间：2018年12月1日 上午11:04:35
	 * 更新记录：
	 * 返回数据：void
	 */
	private void validJoinWhere(LongDbJoinWhere joinWhere) {
		if(null == joinWhere) {
			throw new RuntimeException("要关联查询的对象不能为空！");
		}
		if(StringUtils.isBlank(joinWhere.getWhereTableName()) || 
				StringUtils.isBlank(joinWhere.getJoinTableName())) {
			throw new RuntimeException("要关联查询的表不能为空！");
		}
		if(joinWhere.getOnWhereList().size() <= 0) {
			throw new RuntimeException("没有设置关联[ON]查询的字段！");
		}
	}

	/**
	 * 功能描述：添加需要排序的数据
	 * 模块作者：ZOUYONG
	 * 开发时间：2018年11月15日 下午10:50:39
	 * 更新记录：
	 * 返回数据：LongDbQuery
	 */
	@SuppressWarnings("unused")
	private LongDbQuery addSort(String field, LongDbSortMode asc) {
		if(StringUtils.isBlank(field) || null == asc) {
			return this;
		}
		LongDbSort sort = new LongDbSort(field, asc.name());
		this.sortList.add(sort);
		return this;
	}
	
	/**
	 * 功能描述：是否带查询条件
	 × 模块作者：ZOUYONG
	 × 开发时间：2019年3月27日 下午5:58:15
	 × 返回数据：boolean
	 */
	public boolean isNotQueryCriteria() {
		if(this.longWhereMap.size() == 0 && this.sortList.size() == 0 && this.joinWhereList.size() == 0) {
			return true;
		}
		return false;
	}
	
	/**
	 * 功能描述：是否有排序相关查询
	 × 模块作者：ZOUYONG
	 × 开发时间：2019年3月28日 上午11:13:25
	 × 返回数据：boolean
	 */
	public boolean isSortQuery() {
		if(this.sortList.size() == 0) {
			return false;
		}
		return true;
	}

	public Integer getPageNo() {
		return pageNo;
	}

	public void setPageNo(Integer pageNo) {
		this.pageNo = pageNo;
	}

	public Integer getPageSize() {
		return pageSize;
	}

	public void setPageSize(Integer pageSize) {
		this.pageSize = pageSize;
		if(this.pageSize > 0 && null == this.pageNo) {
			this.pageNo = 1; // 默认取第一页
		}
	}

	public List<LongDbSort> getSortList() {
		return sortList;
	}

	public Class<?> getClassz() {
		return classz;
	}

	public void setClassz(Class<?> classz) {
		this.classz = classz;
	}

	public Map<String, LongDbWhere> getLongWhereMap() {
		return longWhereMap;
	}

	public String getTableName() {
		return tableName;
	}

	public void setTableName(String tableName) {
		this.tableName = tableName;
	}

	public List<LongDbJoinWhere> getJoinWhereList() {
		return joinWhereList;
	}

	public String getYearMothDayArys() {
		return yearMothDayArys;
	}

	public void setYearMothDayArys(String yearMothDayArys) {
		this.yearMothDayArys = yearMothDayArys;
	}

	public Integer getStart() {
		return start;
	}

	public void setStart(Integer start) {
		this.start = start;
	}

	public Integer getTotal() {
		return total;
	}

	public void setTotal(Integer total) {
		this.total = total;
	}

	public Long getQueryTotalCount() {
		return queryTotalCount;
	}

	public void setQueryTotalCount(Long queryTotalCount) {
		this.queryTotalCount = queryTotalCount;
	}

	public boolean isQueryCount() {
		return isQueryCount;
	}

	public void setQueryCount(boolean isQueryCount) {
		this.isQueryCount = isQueryCount;
	}

	public boolean isNeedPage() {
		if(isNeedPage) {
			// 如果需要分页，则判断页码和每页显示数量是否有值
			if(null == this.pageNo || null == this.pageSize) {
				throw new RuntimeException("分页查询的页码和每页显示数量不能为空！");
			}
		}
		return isNeedPage;
	}

	public void setNeedPage(boolean isNeedPage) {
		this.isNeedPage = isNeedPage;
		// 如果不需要分页，则将页码和每页显示数量设置为空
		if(!isNeedPage) {
			this.pageNo = null;
			this.pageSize = null;
		}
	}

	public boolean isTransObject() {
		return transObject;
	}

	public void setTransObject(boolean transObject) {
		this.transObject = transObject;
	}

}

